package me.mouse.gokistats.listener;

import java.util.HashMap;
import java.util.Random;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityShootBowEvent;

import me.mouse.gokistats.GokiStats;
import me.mouse.gokistats.event.TalentTriggerEvent;
import me.mouse.gokistats.talent.RegisterTalent;

public class TalentListener implements Listener {
	private HashMap<UUID, Player> arrow = new HashMap<UUID, Player>();
	private Random r = new Random();

	@EventHandler
	public void onEntityDamageByEntity(EntityDamageByEntityEvent e) {
		if (e.getDamager().getType() == EntityType.PLAYER) {
			Player player = (Player) e.getDamager();
			Material item = player.getItemInHand().getType();
			if (((e.getEntity() instanceof LivingEntity)) && (RegisterTalent.getTalent("deathgod") != null)) {
				LivingEntity le = (LivingEntity) e.getEntity();
				Damageable d = le;
				if (d.getHealth() < 20.0D) {
					if (this.r.nextDouble() < GokiStats.getLevel(player, GokiStats.getDeathGod())
							* GokiStats.config.getDouble("talent.deathgod.deathgod", 0.01D) / 100.0D) {
						TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("deathgod"));
						Bukkit.getServer().getPluginManager().callEvent(event);
						if (!event.isCancelled()) {
							e.setDamage(100.0D);
							return;
						}
					}
				}
			}

			if (((item == Material.WOOD_SWORD) || (item == Material.STONE_SWORD) || (item == Material.IRON_SWORD)
					|| (item == Material.GOLD_SWORD) || (item == Material.DIAMOND_SWORD))
					&& (RegisterTalent.getTalent("sword") != null)) {
				double enddamage = e.getDamage() + e.getDamage() * GokiStats.getLevel(player, GokiStats.getSword())
						* GokiStats.config.getDouble("talent.sword.sword", 2.0D) / 100.0D;
				TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("sword"));
				Bukkit.getServer().getPluginManager().callEvent(event);
				if (!event.isCancelled()) {
					e.setDamage(enddamage);
				}
				return;
			}

			if (((item == Material.WOOD_AXE) || (item == Material.STONE_AXE) || (item == Material.IRON_AXE)
					|| (item == Material.GOLD_AXE) || (item == Material.DIAMOND_AXE))
					&& (RegisterTalent.getTalent("axe") != null)) {
				double enddamage = e.getDamage() + e.getDamage() * GokiStats.getLevel(player, GokiStats.getAxe())
						* GokiStats.config.getDouble("talent.axe.axe", 2.0D) / 100.0D;
				TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("axe"));
				Bukkit.getServer().getPluginManager().callEvent(event);
				if (!event.isCancelled()) {
					e.setDamage(enddamage);
				}
				return;
			}
		}

		if ((e.getDamager().getType() == EntityType.ARROW) && (RegisterTalent.getTalent("arrow") != null)) {
			UUID arrowUUID = e.getDamager().getUniqueId();
			Player player = this.arrow.get(arrowUUID);
			if (player != null) {
				double enddamage = e.getDamage() + e.getDamage() * GokiStats.getLevel(player, GokiStats.getBow())
						* GokiStats.config.getDouble("talent.bow.bow", 2.0D) / 100.0D;
				TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("bow"));
				Bukkit.getServer().getPluginManager().callEvent(event);
				if (!event.isCancelled()) {
					e.setDamage(enddamage);
				}
			}
			this.arrow.remove(arrowUUID);
			return;
		}
	}

	@EventHandler
	public void onEntityDamage(EntityDamageEvent e) {
		if (e.getEntity().getType() == EntityType.PLAYER) {
			if (e.getCause() == EntityDamageEvent.DamageCause.ENTITY_ATTACK) {
				if (RegisterTalent.getTalent("armor") != null) {
					Player player = (Player) e.getEntity();
					double damage = e.getDamage();
					TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("armor"));
					Bukkit.getServer().getPluginManager().callEvent(event);
					if (!event.isCancelled()) {
						double overdamage = damage - damage * GokiStats.getLevel(player, GokiStats.getArmor())
								* GokiStats.config.getDouble("talent.armor.armor", 2.0D) / 100.0D;
						e.setDamage(overdamage);
					}
				}
				return;
			}
			if ((e.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION)
					|| (e.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION)) {
				if (RegisterTalent.getTalent("rubber") != null) {
					Player player = (Player) e.getEntity();
					double damage = e.getDamage();
					TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("rubber"));
					Bukkit.getServer().getPluginManager().callEvent(event);
					if (!event.isCancelled()) {
						double overdamage = damage - damage * GokiStats.getLevel(player, GokiStats.getRubber())
								* GokiStats.config.getDouble("talent.rubber.rubber", 2.0D) / 100.0D;
						e.setDamage(overdamage);
					}
				}
				return;
			}
			if ((e.getCause() == EntityDamageEvent.DamageCause.FIRE_TICK)
					|| (e.getCause() == EntityDamageEvent.DamageCause.FIRE)
					|| (e.getCause() == EntityDamageEvent.DamageCause.LAVA)) {
				if (RegisterTalent.getTalent("fire") != null) {
					Player player = (Player) e.getEntity();
					double damage = e.getDamage();
					TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("fire"));
					Bukkit.getServer().getPluginManager().callEvent(event);
					if (!event.isCancelled()) {
						double overdamage = damage - damage * GokiStats.getLevel(player, GokiStats.getFire())
								* GokiStats.config.getDouble("talent.fire.fire", 2.0D) / 100.0D;
						e.setDamage(overdamage);
					}
				}
				return;
			}
			if (e.getCause() == EntityDamageEvent.DamageCause.FALL) {
				if (RegisterTalent.getTalent("fall") != null) {
					Player player = (Player) e.getEntity();
					double damage = e.getDamage();
					TalentTriggerEvent event = new TalentTriggerEvent(player, RegisterTalent.getTalent("fall"));
					Bukkit.getServer().getPluginManager().callEvent(event);
					if (!event.isCancelled()) {
						double overdamage = damage - damage * GokiStats.getLevel(player, GokiStats.getFall())
								* GokiStats.config.getDouble("talent.fall.fall", 2.0D) / 100.0D;
						e.setDamage(overdamage);
					}
				}
				return;
			}
		}
	}

	@EventHandler
	public void onEntityShootBow(EntityShootBowEvent e) {
		if ((RegisterTalent.getTalent("arrow") != null) && (e.getEntityType() == EntityType.PLAYER)
				&& (e.getProjectile().getType() == EntityType.ARROW)) {
			Player player = (Player) e.getEntity();
			UUID arrowUUID = e.getProjectile().getUniqueId();
			this.arrow.put(arrowUUID, player);
		}
	}
}
